!------------------------------------------------------------------------------
! TJU/Department of Mechanics, Fluid Mechanics, Code START
!------------------------------------------------------------------------------
!
!  File: module_dis_wavenum.f90
!> @file
!> @breif 扰动色散参数相关文件.
!  DESCRIPTION:
!>
!------------------------------------------------------------------------------

!------------------------------------------------------------------------------
! TJU/Department of Mechanics, Fluid Mechanics, Code START
!------------------------------------------------------------------------------
!
!  module: dis_wavenum
!> @breif 扰动色散参数相关模块.
!  DESCRIPTION:
!>
!!
!  REVISION HISTORY:
!  2018-09-14 - Initial Version
!> @author
!> Liu Jianxin
!> \date 2018-09-14
!------------------------------------------------------------------------------`
module mod_dis_wavenum

    use penf, only: R_P
    implicit none
    private

    !> 扰动色散关系类型
    type, public :: dis_wavenum_type

        complex(R_P) :: alpha !< 流向波数\f$\alpha\f$
        complex(R_P) :: omega !< 频率\f$\omega\f$

        Contains

          procedure :: Print !< 输出波数信息
          procedure :: Write !< 写入波数信息
          procedure :: Read !< 读取波数信息

          generic :: Set => set_alpha_omega !< 设置扰动色散信息
          generic :: Get => get_alpha_omega !< 获得扰动色散信息

          procedure, private :: set_alpha_omega !< 设置波数和频率信息
          procedure, private :: get_alpha_omega !< 获得波数和频率信息

    end type dis_wavenum_type

    ! !> 适用于PSE的扰动色散信息
    ! !!
    ! !! 添加了一个字段表示流向波数随流向的导数
    ! type, extends(dis_wavenum_type), public :: dis_wavenum_lpse_type
    !
    !     private
    !     complex(R_P), private :: Dx_alpha=0.0d0 !< 流向波数沿流向的导数
    !
    !     contains
    !     procedure :: SetDxAlpha => set_Dx_alpha !< 设置流向波数沿流向的导数
    !     procedure :: GetDxAlpha => Get_Dx_Alpha !< 获得流向波数沿流向的导数
    !
    !     generic :: operator(*) => mul_scalar_lpse_type !< 数乘(标量乘)
    !     generic :: operator(+) => add_wavenum_lpse   !< 加法操作
    !     procedure, pass(this), private :: mul_scalar_lpse_type !<标量乘类型
    !     procedure, pass(this), private :: add_wavenum_lpse !< 加法操作
    !
    ! end type

    contains

    !> 设置扰动的波数和频率信息
    !! @param[in] alpha 流向波数\f$\alpha\f$
    !! @param[in] omega 频率\f$\omega\f$
    pure subroutine set_alpha_omega(this, alpha, omega)

        implicit none
        complex(R_P), intent(in) :: alpha, omega
        class(dis_wavenum_type), intent(inout) :: this

        this%alpha=alpha; this%omega=omega

    end subroutine set_alpha_omega

    ! !> 设置扰动流向波数沿流向的导数
    ! !! @param[in] Dx_alpha 流向波数沿流向的导数
    ! subroutine set_Dx_alpha(this, Dx_alpha)
    !
    !     implicit none
    !     complex(R_P), intent(in) :: Dx_alpha
    !     class(dis_wavenum_lpse_type), intent(inout) :: this
    !
    !     this%Dx_alpha=Dx_alpha
    !
    ! end subroutine set_Dx_alpha
    !
    ! !> 获得扰动流向波数沿流向的导数\f$ \partial{\alpha} / \partial{x}\f$
    ! !! @return 流向波数沿流向的导数
    ! function Get_Dx_Alpha(this) result(Dx_alpha)
    !
    !     implicit none
    !     class(dis_wavenum_lpse_type), intent(in) :: this
    !     complex(R_P) :: Dx_alpha
    !
    !     Dx_alpha=this%Dx_alpha
    !
    ! end function Get_Dx_Alpha

    !> 获得扰动的波数和频率信息
    !! @param[out] alpha 流向波数\f$\alpha\f$
    !! @param[out] omega 频率\f$\omega\f$
    pure subroutine get_alpha_omega(this, alpha, omega)

        implicit none
        class(dis_wavenum_type), intent(in) :: this
        complex(R_P), intent(inout) :: alpha, omega

        alpha=this%alpha; omega=this%omega

    end subroutine get_alpha_omega

    !> 输出波数信息
    subroutine Print(this)

        implicit none
        class(dis_wavenum_type),intent(inout) :: this

        write(*,"(1x, 'omega=', 2F20.8)") this%omega
        write(*,"(1x, 'alpha=', 2F20.8)") this%alpha

    end subroutine Print

    !> 写入波数信息
    subroutine write(this, unit)
      implicit none
      class(dis_wavenum_type), intent(in) :: this
      integer, intent(in) :: unit

      write(unit)this%omega, this%alpha

    end subroutine write

    !> 读取波数信息
    subroutine read(this, unit)
      implicit none
      class(dis_wavenum_type), intent(inout) :: this
      integer, intent(in) :: unit

      read(unit)this%omega, this%alpha

    end subroutine read

    ! !> 标量乘
    ! function mul_scalar_lpse_type(scalar, this) result(mul)
    !
    !     implicit none
    !     real(R_P), intent(in) :: scalar
    !     class(dis_wavenum_lpse_type), intent(in) :: this
    !     type(dis_wavenum_lpse_type) :: mul
    !
    !     call mul%set(scalar*this%alpha, scalar*this%beta, scalar*this%omega)
    !
    ! end function mul_scalar_lpse_type
    !
    ! !> 类型相加
    ! function add_wavenum_lpse(this, obj) result(add)
    !
    !     implicit none
    !     class(dis_wavenum_lpse_type), intent(in) :: this
    !     type(dis_wavenum_lpse_type), intent(in) :: obj
    !     type(dis_wavenum_lpse_type) :: add
    !
    !     call add%set(this%alpha+obj%alpha, this%beta+obj%beta, this%omega+obj%omega)
    !
    ! end function add_wavenum_lpse

end module mod_dis_wavenum
